package com.idas.db;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Set;

public class DBFilter {

	private static DBFilter dbFilterInstance = null;
	private static HashMap<Class, Hashtable<String, FieldData>> classDBMap = new HashMap<Class, Hashtable<String, FieldData>>();

	private DBFilter() {

	}

	public static DBFilter getInstance() {
		if (dbFilterInstance == null)
			dbFilterInstance = new DBFilter();
		return dbFilterInstance;
	}

	public static synchronized void registerClass(Class c) {

		if (classDBMap.containsKey(c)) {
			return;
		} else {
			Hashtable<String, FieldData> ht = new Hashtable<String, FieldData>();
			classDBMap.put(c, ht);
			addFields(c.getDeclaredFields(), ht, null);

			if (!c.getSuperclass().equals(Object.class)) {
				registerClass(c.getSuperclass());
				Hashtable<String, FieldData> sht = classDBMap.get(c
						.getSuperclass());
				ht.putAll(sht);
			}
		}
	}

	public Set<Class> getRegisteredClasses() {
		return classDBMap.keySet();
	}

	private static void addFields(Field[] fields,
			Hashtable<String, FieldData> dbDetails, String prefix) {

		if (fields == null || fields.length == 0)
			return;

		if (prefix == null)
			prefix = "";

		for (Field field : fields) {
			DBFields fil = field.getAnnotation(DBFields.class);
			if (fil != null && fil.linkedClass() == DBFields.class) {
				FieldData fd = new FieldData();
				fd.filterField = field.getName();
				fd.type = field.getType();
				fd.dbField = fil.field();
				fd.dbTable = fil.table();
				dbDetails.put(prefix.toLowerCase() + field.getName().toLowerCase(), fd);
				if (fil.orderby())
					dbDetails.put("ORDERBYFIELDON", fd);

			} else if (fil != null && fil.linkedClass() != null) {
				addFields(fil.linkedClass().getDeclaredFields(), dbDetails,
						field.getName());
			}
		}
	}

	public Hashtable<String, FieldData> getDBDetails(Class c) {
		return classDBMap.get(c);
	}
}

class FieldData {
	public String filterField;
	public String dbTable;
	public String dbField;
	public Class type;
}